﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SPC
{
    class SpcXRm : ISPC
    {
        double usl = 0;
        double lsl = 0;        
        double xbar;
        double[] x;
        double[] rm;
        double rmbar;
        double sigmaC;
        double sigmaP;
        int groupCapacity = 2;//顺序相减
        public SpcXRm(double[] x, double usl, double lsl)
        {
            this.usl = usl;
            this.lsl = lsl;
            xbar = x.Average();
            this.x = x;
            rm = new double[x.Length - 1];
            for (int i = 1; i < x.Length; i++)
            {
                rm[i - 1] = Math.Abs(x[i] - x[i - 1]);
            }
            rmbar = rm.Average();
            sigmaC = rmbar / CtrlChartFactor.Factor(groupCapacity, "d2");
            sigmaP = CaculateSigmaP(x);
        }
        private double CaculateSigmaP(double[] x)
        {
            double sum = 0;
            for (int i = 0; i < x.Length; i++)
            {
                sum += Math.Pow(x[i] - xbar, 2);
            }
            return Math.Sqrt(sum / (x.Length - 1));
        }
        public double LSL
        { set { lsl = value; } }
        public double USL
        { set { usl = value; } }
        public double CP()
        {
            double cp = 0;
            if (usl != 0 && lsl != 0)
            { cp = (usl - lsl) / (6 * sigmaC); }
            else if (usl != 0)
            { cp = (usl - xbar) / (3 * sigmaC); }
            else
            { cp = (xbar - lsl) / (3 * sigmaC); }
            return cp;
        }

        public double CPK()
        {
            double cpu = 0, cpl = 0;
            if (usl != 0) { cpu = (usl - xbar) / (3 * sigmaC); }
            if (lsl != 0) { cpl = (xbar - lsl) / (3 * sigmaC); }
            double[] cps = { cpu, cpl };
            return cps.Min();
        }

        public SCtrlDiagram[] GetCtrlDiagrams()
        {
            SCtrlDiagram[] diags = new SCtrlDiagram[2];
            double lcl = xbar - rmbar * CtrlChartFactor.Factor(groupCapacity, "E2");
            diags[0] = new SCtrlDiagram()
            {
                diagramName = DiagramName.X,
                cl = xbar,
                lcl = lcl > 0 ? lcl : 0,
                ucl = xbar + rmbar * CtrlChartFactor.Factor(groupCapacity, "E2"),
                points = x
            };
            diags[1] = new SCtrlDiagram()
            {
                diagramName = DiagramName.Rm,
                cl = rmbar,
                lcl = rmbar * CtrlChartFactor.Factor(groupCapacity, "D3"),
                ucl = rmbar * CtrlChartFactor.Factor(groupCapacity, "D4"),
                points = rm
            };            
            return diags;
        }

        public double PP()
        {
            double pp = 0;
            if (usl != 0 && lsl != 0)
            { pp = (usl - lsl) / (6 * sigmaP); }
            else if (usl != 0)
            { pp = (usl - xbar) / (3 * sigmaP); }
            else
            { pp = (xbar - lsl) / (3 * sigmaP); }
            return pp;
        }

        public double PPK()
        {
            double ppu = 0, ppl = 0;
            if (usl != 0) { ppu = (usl - xbar) / (3 * sigmaP); }
            if (lsl != 0) { ppl = (xbar - lsl) / (3 * sigmaP); }
            double[] pps = { ppu, ppl };
            return pps.Min();
        }
    }
}
